package ExactMsa;

import java.util.Hashtable;


public class PairwiseGlobalAlignment {


	/******************************************************************************
	 * Modified pairwise global alignment of Project One.
	 * It needs two sequences, a score matrix and gap costs as input.
	 *
	 * !!NOTE!!
	 * Just holds the alignment matrix D in memory, this means no traceback is possible
	 */

	/**
	 * CONSTRUCTOR
	 */
	PairwiseGlobalAlignment(Hashtable<String,Hashtable<String,String>> scoMat,String is1,String is2,int gap){

		scoreMatrix = scoMat;
		setGapScore(gap);

		seq1=is1;
		seq2=is2;
		alignmentMatrix  = new int[seq1.length()+1][seq2.length()+1];
		computeOptimalAlignment();
	}


	/**
	 * DESTRUCTOR
	 * @return
	 */
	protected void finalize(){

	}


	private String seq1; // Sequence 1
	private String seq2; // Sequence 2

	private int gapCost = -1;

	private Hashtable<String,Hashtable<String,String>> scoreMatrix;

	private int[][] alignmentMatrix;


	/**
	 *  Setter-Methods
	 */

	public void setGapScore(int score){gapCost=score;}




	/**
	 * Getter Methods
	 */

	public int getValueInAlignmentMatrix(int i,int j){
		return alignmentMatrix[i][j];
	}



	/**
	 * This function returns the score for two characters from a given score matrix
	 */
	public int matchScore(char a,char b){

			String score 	= ((Hashtable<String,String>) scoreMatrix.get(""+a)).get(""+b).toString();
			return Integer.parseInt(score);
	}

	/**
	 * Computes the optimal global alignment of two sequences.
	 * Input parameters are global variables from above.
	 */

	public void computeOptimalAlignment(){

		int n = seq1.length();
		int m = seq2.length();


		// Initialization
		for(int i = 0; i<=n; i++){
			alignmentMatrix[i][0] = i*gapCost;
		}
		for(int j = 0; j<=m; j++){
			alignmentMatrix[0][j] = j*gapCost;
		}


		// Filling up the table
		for(int i = 1; i<=n;i++){

			for(int j = 1; j<=m;j++){
				alignmentMatrix[i][j] = Math.min(
											Math.min(
													alignmentMatrix[i-1][j] + gapCost,
													alignmentMatrix[i][j-1] + gapCost
											),
													alignmentMatrix[i-1][j-1] + matchScore(seq1.charAt(i-1),seq2.charAt(j-1))
									);
			}
		}


	}

}
